#include "mbx.h"

int openNewMbx(MBX **mbx, const char *name, int buffSize) {
	if (!(*mbx = (MBX *) rt_mbx_init(nam2num(name), buffSize+9))) {
		return -1;
	}
	return 0;
}

int openNewMbxBuf(MBX **mbx, const char *name, int buffSize, int sizeBuf) {
	if (!(*mbx = (MBX *) rt_mbx_init(nam2num(name), (buffSize+9)*sizeBuf))) {
		return -1;
	}
	return 0;
}

int openExistingMbx(MBX **mbx, const char *name) {
	if (!(*mbx = (MBX *) rt_get_adr(nam2num(name)))) {
		return -1;
	}
	return 0;
}

int sendViaMbx(MBX *mbx, void *data, uint32_t sizeIn) {
	int i=0;
    int count=0;
	uint32_t checksum=0;
	unsigned char tmp;

	// build checksum
	for(i=0; i<sizeIn; i++) {
		checksum = checksum  + ((unsigned char*)data)[i];
	}

	tmp = 0xFA;
	if ((count = rt_mbx_send_if(mbx, &tmp, 1))) {  //send preeamble
		if (count == 1) {
			//_MY_PRINTLF_S("Mailbox seems to be full");
		} else if (count == -EINVAL) {
			_MY_PRINTLF_S("Pointer to an invalid mailbox");
		} else {
			_MY_PRINTLF_S_I("Weard stuff happens", count);
		}
		return -1;
	}

	if ((count = rt_mbx_send_if(mbx, &sizeIn, sizeof(sizeIn)))) {  //send size
		if (count == sizeof(sizeIn)) {
			//_MY_PRINTLF_S("Mailbox seems to be full");
		} else if (count == -EINVAL) {
			_MY_PRINTLF_S("Pointer to an invalid mailbox");
		} else {
			_MY_PRINTLF_S_I("Weard stuff happens", count);
		}
		return -2;
	}

	if ((count = rt_mbx_send_if(mbx, &checksum, sizeof(checksum)))) {  //send checksum
		if (count == sizeof(checksum)) {
			//_MY_PRINTLF_S("Mailbox seems to be full");
		} else if (count == -EINVAL) {
			_MY_PRINTLF_S("Pointer to an invalid mailbox");
		} else {
			_MY_PRINTLF_S_I("Weard stuff happens", count);
		}
		return -3;
	}

	if ((count = rt_mbx_send_if(mbx, data, sizeIn))) {  //send data
		if (count == sizeIn) {
			//_MY_PRINTLF_S("Mailbox seems to be full");
		} else if (count == -EINVAL) {
			_MY_PRINTLF_S("Pointer to an invalid mailbox");
		} else {
			_MY_PRINTLF_S_I("Weard stuff happens", count);
		}
		return -4;
	}

	return 0;
}


int receiveViaMbx(MBX *mbx, void *data, uint32_t sizeMax) {
	int count=0, i=0;
    uint32_t size=0, checkSum=0;

    unsigned char tmp = 0;
    do {
        if ((count = rt_mbx_receive_if(mbx, (void *) &tmp, 1)) < 0) {
			if (count == -EINVAL) {
				_MY_PRINTLF_S("Pointer to an invalid mailbox");
			} else {
            	_MY_PRINTLF_S_I("Receiving Error ", count);
			}
            return -1;
        }
        if (count != 0) { return 0;} /*MBX empty*/
    } while (tmp != 0xfa );
	/* the starting flag of new data was received */

	if ((count = rt_mbx_receive(mbx, &size, sizeof(uint32_t)))) {
		_MY_PRINTLF_S("Receiving Error, seems there is no data.");
		return -2;
    }
    size = (sizeMax < size) ? sizeMax : size;

	if ((count = rt_mbx_receive(mbx, &checkSum, sizeof(uint32_t)))) {
		_MY_PRINTLF_S("Receiving Error, seems there is no data.");
		return -3;
    }

	if (count == 0 && size > 0){
		if ((count = rt_mbx_receive(mbx, data, size))) {
			_MY_PRINTLF_S("Receiving Error, seems there is no data.");
			return -4;
		}

		//evaluate checksum
		for(i=0; i<size; i++) {
			checkSum = checkSum  - ((unsigned char*)data)[i];
		}
	} else {
		return -10; /* just for safty, should not be reached */
	}

	if (checkSum != 0) {
		size = 0;
		return -99;
	}

	return size;
}

int closeMbx(MBX *mbx) {
	int status = rt_mbx_delete(mbx);
	if (status == -EINVAL) {
		_MY_PRINTLF_S("Pointer to an invalid mailbox");
	} else if (status == -EFAULT) {
		_MY_PRINTLF_S("Mailbox data were found in an invalid state");
	}

	return status;
}
